package game;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;

public class Snake extends Unit implements KeyListener
{
	private int xVel = 10;
	private int yVel;
	private Unit[] snake;
	private ArrayList<Target> target;
	private boolean gameOver = false;
	private boolean flag = false;
	private int score = 0;
	private int direction;
	private int snakePart;

	public Snake(int a, int b, int s)
	{
		x = a;
		y = b;
		snake = new Unit[3];
		if(xVel > 0)
		{
			direction = 0;
		}
		if(xVel < 0)
		{
			direction = 1;
		}
		if(yVel < 0)
		{
			direction = 2;
		}
		if(yVel > 0)
		{
			direction = 3;
		}
		for(int i = 0; i < snake.length; i++)
		{
			snake[i] = new Unit(x, y, direction);
			if(i != 0)
			{
				snake[i].setNextDir(snake[i - 1].getDir());
			}
		}
		score = s;
	}
	public Snake(int s)
	{
		this(30, 30, s);
	}
	public Snake(int a, int b)
	{
		this(a,b,0);
	}
	public Snake()
	{
		this(30, 30, 0);
	}

	public void moveUnit()
	{
		if(!flag)
		{
			if(xVel > 0)
			{
				direction = 0;
			}
			if(xVel < 0)
			{
				direction = 1;
			}
			if(yVel < 0)
			{
				direction = 2;
			}
			if(yVel > 0)
			{
				direction = 3;
			}
			
			x = snake[0].getX();
			y = snake[0].getY();

			x = x + xVel;
			y = y + yVel;

			if(x > Map.getWidth()*10-10)
			{
				x = 0;
			}
			if(y > Map.getHeight()*10-10)
			{
				y = 0;
			}
			if(x < 0)
			{
				x = Map.getWidth()*10-10;
			}
			if(y < 0)
			{
				y = Map.getHeight()*10-10;
			}
			if(Map.isHazard(x, y))
			{
				removeUnit();
			}
			if(outOfBounds(x, y) || snake.length < 2)
			{
				gameOver = true;
			}
			for(int i=0; i<target.size(); i++)
			{
				if(target.get(i).Hit(x, y))
				{
					addUnit();
					score++;
					//if(target.size() > 1)
					{
						target.remove(i);
					}
				}
			}
			if(!gameOver)
			{
				for(int i = snake.length - 1; i > 0; i--)
				{
					snake[i] = snake[i - 1];
				}
	
				snake[0] = new Unit(x, y, direction);
				snake[1].setNextDir(direction);
			}
		}
		flag = false;
	}
	public void setTarget(ArrayList<Target> t)
	{
		target = t;
	}

	public int getScore()
	{
		return score;
	}

	public boolean outOfBounds(int a, int b)
	{
		boolean on = false;
		for(int i = 0; i < snake.length - 1; i++)
		{
			if(snake[i].Hit(a, b))
			{
				on = true;
			}
		}
		if(on == false)
		{
			on = Map.isSolid(a, b);
		}
		return on;
	}
	public void addUnit()
	{
		Unit[] newUnit = new Unit[snake.length + 1];
		for(int i = 0; i < snake.length; i++)
		{
			newUnit[i] = snake[i];
		}
		snake = newUnit;
	}
	public void removeUnit()
	{
		Unit[] newUnit = new Unit[snake.length - 1];
		for(int i = 0; i < snake.length - 1; i++)
		{
			newUnit[i] = snake[i];
		}
		snake = newUnit;
	}
	public void paint(Graphics g)
	{
		moveUnit();
		
		for(int i = 0; i < snake.length; i++)
		{
			if(i != 0 && i != snake.length -1)
			{
				snakePart = 0;
			}
			else
			{
				if(i == 0)
				{
					snakePart = 1;
				}
				else
				{
					snakePart = 2;
				}
			}
			snake[i].paint(g, snakePart);
		}
	}
	public boolean checkGameOver()
	{
		return gameOver;
	}
	public int speedCheck()
	{
		return Map.checkSpeed(snake[0].getX(), snake[0].getY());
	}
	public void keyTyped(KeyEvent e){}

	public void keyPressed(KeyEvent e)
	{

		if(yVel == 0)
		{
			if(e.getKeyCode() == KeyEvent.VK_UP)
			{
				xVel = 0;
				if(Map.reverseControl(x, y))
				{
					yVel = 10;
				}
				else
				{
					yVel = -10;
				}
			}
			if(e.getKeyCode() == KeyEvent.VK_DOWN)
			{
				xVel = 0;
				if(Map.reverseControl(x, y))
				{
					yVel = -10;
				}
				else
				{
					yVel = 10;
				}
			}
		}
		if(xVel == 0)
		{
			if(e.getKeyCode() == KeyEvent.VK_LEFT)
			{
				yVel = 0;
				if(Map.reverseControl(x, y))
				{
					xVel = 10;
				}
				else
				{
					xVel = -10;
				}
			}
			if(e.getKeyCode() == KeyEvent.VK_RIGHT)
			{
				yVel = 0;
				if(Map.reverseControl(x, y))
				{
					xVel = -10;
				}
				else
				{
					xVel = 10;
				}
			}
		}
		moveUnit();
		flag = true;
	}

	public void keyReleased(KeyEvent e){}
}
